package deyi.utils;

import com.alibaba.fastjson.JSONObject;
import deyi.log.AppLogger;
import deyi.nbtype.DeviceConfigInfo;
import deyi.nbtype.DeviceDataSign;
import fr.devnied.bitlib.BytesUtils;
import org.apache.commons.codec.binary.Base64;
import org.joda.time.DateTime;
import sun.misc.BASE64Decoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


public class NBHandler {
    /**
    @函数描述:获取时间戳
    **/
    public static byte[] getTimeBytes(){
        DateTime time = DateTime.now();
        String timeStr = time.toString("yyMMddHHmm");
        int timeInt = Integer.parseInt(timeStr);
        return BytesUtils.toByteArray(timeInt);

    }

    /**
    @函数描述:udp接收到nb数据反馈帧
    **/
    public static byte[] getReplyFrame(byte[] nbsn){
        short frameLen = 23;
        byte[] frame = new byte[frameLen];
        //头尾帧
        frame[0] = (byte)0xaa;
        frame[frameLen-1] = (byte)0xab;
        //构造id
        System.arraycopy(nbsn,0,frame,3,12);
        //构造ktv
        frame[15] = 0x06;
        frame[16] = 0x01;
        byte[] timeBytes = getTimeBytes();
        short dateLen = (short)(timeBytes.length + 2);
        System.arraycopy(CommonUtil.shortToByte(dateLen), 0, frame,1,2);
        System.arraycopy(timeBytes,0,frame,17,4);
        //构造校验字
        frame[21] = getVerifyByte(frame);
        return frame;
    }

    public static byte[] getAppToNbFrame(String nbsn, byte[] data){
        short frameLen = (short) (17 + data.length);
        byte[] frame = new byte[frameLen];
        frame[0] = (byte)0xaa;
        System.arraycopy(CommonUtil.shortToByte((short)data.length), 0, frame,1,2);
        byte[] arr = nbsn.getBytes();
        System.arraycopy(arr,0,frame,3,arr.length);

        System.arraycopy(data, 0, frame, 15, data.length);
        frame[frameLen-2] = getVerifyByte(frame);
        frame[frameLen-1] = (byte)0xab;
        return frame;
    }


    /**
    @函数描述:块传输传给设备的配置帧
    **/
    public static byte[] getConfigFrame(String sn,byte[] configData){
        //sn = ((AppConfig)SpringContextUtil.getBean("appconfig")).getDevicePrefix() + sn;
        byte[] nbarr = sn.getBytes();
        short frameLen = (short)(6 + nbarr.length + configData.length);
        byte[] frame = new byte[frameLen];
        frame[0] = 0;
        frame[1] = 0;
        frame[2] = 0;
        byte[] len = CommonUtil.shortToByte((short)(configData.length));
        System.arraycopy(len,0,frame,3,2);
        frame[5] = 0x59;
        System.arraycopy(nbarr,0,frame,6,nbarr.length);
        System.arraycopy(configData,0,frame,6+nbarr.length,configData.length);
        return frame;
    }

    /**
    @函数描述:设备配置结果的json格式
    **/
    public static JSONObject getConfigReJsonsult(String sn, int serialNum, int result){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("deviceSn",sn);
        jsonObject.put("configSerialNumber",String.valueOf(serialNum));
        jsonObject.put("configResult",String.valueOf(result));
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = formatter.format(new Date());
        jsonObject.put("deviceConfigTime",date);
        return jsonObject;
    }

    public static byte[] getProduceConfigData(DeviceConfigInfo info){
        byte[] configData = new byte[7];
        System.arraycopy(CommonUtil.intToByteArray(info.getConfigId()),0,configData,0,4);
        configData[4] = (byte)info.getDeviceStatus();
        return configData;
    }


    /**
    @函数描述:校验
    **/
    public static byte getVerifyByte(byte[] bytes){
        byte check = bytes[1];
        for(int i=2; i<bytes.length-2; i++){
            check ^= bytes[i];
        }
        return check;
    }

    /**
     @函数描述:获取块传输协议帧号
     **/
    public static int getBlockFrameSeqNum(byte b1, byte b2){
        return CommonUtil.bytesToShort(b1,b2);
    }

    /**
     @函数描述:获取块传输协议帧长
     **/
    public static int getBlockFrameLen(byte b1,byte b2){
        return CommonUtil.bytesToShort(b1,b2);
    }

    /**
    @函数描述:块传输协议应答帧
    **/
    public static byte[] reponseBlockFrame(byte b1,byte b2,byte b3, byte[] nbarr, boolean head){
        int frameLen = 19;
        byte[] frame = new byte[frameLen];
        frame[0] = b1;
        frame[1] = b2;
        frame[2] = b3;
        byte[] bytes = CommonUtil.shortToByte((short)1);
        frame[3] = bytes[0];
        frame[4] = bytes[1];
        frame[5] = (head)? (byte)0x0a : (byte)0x4a;
        System.arraycopy(nbarr,0,frame,6,nbarr.length);
        frame[frameLen-1] = 0;
        return frame;
    }

    /**
    @函数描述:块传输协议缺失应答帧
    **/
    public static byte[] responseBlockLackFrame(List<Integer> list,byte b1,byte b2,byte b3, byte[] nbarr){
        int frameLen = 18+list.size()*2+1;
        byte[] frame = new byte[frameLen];
        frame[0] = b1;
        frame[1] = b2;
        frame[2] = b3;
        byte[] bytes = CommonUtil.shortToByte((short)(list.size()*2+1));
        frame[3] = bytes[0];
        frame[4] = bytes[1];
        frame[5] = 0x0a;
        System.arraycopy(nbarr,0,frame,6,nbarr.length);
        frame[18] = 0x01;
        for(int i=0; i<list.size(); i++){
            int num = list.get(i);
            short realNum = (short)num;
            byte[] shortbytes = CommonUtil.reverseShortToByte(realNum);
            System.arraycopy(shortbytes,0,frame,19+i*2,shortbytes.length);
        }
        return frame;
    }

    /**
    @函数描述:获取块数据标志
    **/
    public static DeviceDataSign getDeviceDataSign(byte[] deviceData){
        DeviceDataSign deviceDataSign = new DeviceDataSign();
        byte[] nbArr = new byte[12];
        System.arraycopy(deviceData,6,nbArr,0,12);
        if (nbArr[10]==0X00){
            byte[] nbArr2 = new byte[10];
            for (int i = 0; i < 10; i++) {
                nbArr2[i]=nbArr[i];
            }
            nbArr=nbArr2;
        }
        String nbsn = new String(nbArr);
        //获取块号
        int blockNum = (deviceData[0]);
        //获取帧号
        int blockFrameNum = NBHandler.getBlockFrameSeqNum(deviceData[1],deviceData[2]);
        //获取帧长
        int blockFrameLen = NBHandler.getBlockFrameLen(deviceData[3],deviceData[4]);
        //获取块标志
        int blockSig = (int)(deviceData[5] >> 5 & 0x03);
        //获取可靠传输标志
        int reliableTrans = (int)(deviceData[5] >> 4 & 0x01);
        deviceDataSign.setSn(nbsn);
        deviceDataSign.setBlockNum(blockNum);
        deviceDataSign.setBlockFrameNum(blockFrameNum);
        deviceDataSign.setBlockFrameLen(blockFrameLen);
        deviceDataSign.setBlockSig(blockSig);
        deviceDataSign.setReliableTrans(reliableTrans);
        deviceDataSign.setSnBytes(nbArr);
        return deviceDataSign;
    }

}
